iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
Software Development

RISC-V 與處理器之架構學習及應用系列 第 4

[Day04] RISC-V Instructions (2/3)

  • 分享至 

  • xImage
  •  

一、RISC-V 中的 Arithmetic Operators(算術運算符)

  1. 基本說明
    • Arithmetic Operators 用於在 register 之間,或在 register 和 immediate 之間進行數學運算。
  2. RISC-V 指令集中的基本操作
    • 加減法add, sub, addi
    • 位元運算and, or, xor, andi, ori, xori
    • 位移操作
      • sll (Shift Left Logical) 左移
      • srl (Shift Right Logical) 右移
      • sra (Shift Right Arithmetic) 算術右移
      • slli, srli, srai:對應的 immediate 操作版本
    • 小於比較slt, sltu, slti, sltiu
      • sltsltu 用於符號和無符號數的比較。
      • sltisltiu 則是 immediate 版本。
  3. 小於比較操作的說明
    • 例如:slt x5, x6, x7 的意思是:
      • 如果 x6 < x7,那麼 x5 被設置為 1;否則,設為 0。
    • 提供兩種版本:
      • slt:操作數被視為有符號數。
      • sltu:操作數被視為無符號數。
      • 對應的 immediate 版本是 sltisltiu,用於 immediate 比較。
  4. 乘除法:不包含在基本指令集中,因為乘除法需要 O(n²) 的電路元件,因此被放在選擇性擴展指令集中。

二、Arithmetic vs. Logical Shifts

  1. Logical Left Shift
    • 將所有位元向左移動,並在右邊補零。
  2. Logical Right Shift
    • 將所有位元向右移動,並在左邊補零。
  3. 回顧
    • 在處理無符號數時,邏輯左移相當於乘以 2 的冪次方,而邏輯右移則是除以 2 的冪次方(向下取整)。
  4. 對於有符號數的移位
    • 左移操作不變,直接移動並補零。
    • 右移時,如果使用邏輯右移,則補零會導致負數變成正數,這會改變數值的符號。
  5. 解決有符號數的右移
    • 問題:如果我們想要相同的行為對於有符號數,邏輯右移可能導致負數變成正數,因為補零操作。
    • 解決方案:對於右移操作,如果數字是負數,應該在前面補上 1 而不是 0,以保持數值的負號。
    • 原因:
      • 負數的二進位表示通常以「1」作為最左邊的位元(最高位,MSB)。例如,-3 的 16 位元二進位補碼表示為 0b1111 1111 1111 1101
      • 如果將這個數字從 16 位延展到 20 位,我們可以在最左邊補 1 來保持負號。
    • 結論:
      • 如果我們要右移或擴展一個有符號數,應該使用最左邊的位元(MSB)來填充擴展部分,以保持原來的值。這個操作稱為「符號延伸 (sign-extension)」。

三、Logical Shifting

  1. Shift Left Logical, sll 和 immediate 形式 (slli)
    • 指令格式:slli x11, x12, 2
    • 這條指令的意思是將 register x12 中的數值向左移動 2 位,結果存入 register x11
    • 例如:
      • 移位前:0b0000 0000 0000 0000 0000 0000 0000 0010(表示數值 2)
      • 移位後:0b0000 0000 0000 0000 0000 0000 0000 1000(表示數值 8)
    • 左移操作會將位元向左移動指定的位數,在右邊補零,類似於 C 語言中的 << 操作符。
  2. Shift Right Logical, srl 和 immediate 形式 (srli)
    • 右移的操作類似左移,但方向相反,將數值向右移動,並在左邊補零。
    • 這些指令的格式和行為與左移類似,只是方向不同。

四、Arithmetic Shifting

  1. 算術右移(Shift Right Arithmetic, sra, srai)
    • Shift Right Arithmetic 將 register 中的數值按位向右移動指定的位數,並在左邊空出的高位插入符號位(即保持數字的正負不變)。
    • 指令格式:srai x10, x10, 4
    • 範例:
      • 假設 register x10 中的值是 0b1111 1111 1111 1111 1111 1111 1110 0111(表示 -25)。
      • 執行 srai x10, x10, 4 的結果是 0b1111 1111 1111 1111 1111 1111 1111 1110(表示 -2)。
    • Shift Right Arithmetic 有效地保持了符號位,使得負數仍然是負數。
  2. Shift Right Arithmetic 與除法的差異
    • Shift Right Arithmetic 並不完全等同於除以 2 的冪次。
    • 特別是對於負數,尤其是奇數的情況,結果不會完全等於數學上的除法。
    • 在 C 語言中,除法會將結果向零取整,但 Shift Right Arithmetic 不一定符合這一點。
  3. 左移無算術版本
    • 左移不分有符號或無符號,因此沒有「Shift left Arithmetic」的概念,因為左移操作只需將位元往左移並補零,不受符號影響。

五、Memory Instructions(記憶體指令)

  1. Memory Instructions 主要功能:
    • 允許數據在主記憶體和 register 之間進行轉換。
    • 與 Arithmetic Instructions 相比,語法有所不同。
  2. 常用的記憶體指令:
    • lw x5,12(x7):將 x7 解釋為地址並加上 12,從該位置讀取下一個 4 字節的數據,將結果儲存於 x5。
    • sw x5,12(x7):將 x7 解釋為地址並加上 12,用 x5 中的值覆蓋該位置的 4 字節數據。
  3. Load from Memory to Register:
    • 例子:從陣列 A 中取出第 3 個元素,並計算 g = h + A[3]
      • 使用指令:lw x10,12(x15)add x11,x12,x10,x15 是指向 A[0] 的指標,偏移量是 12。
  4. Store from Register to Memory:
    • 例子:將運算後的結果存回陣列 A,A[10] = h + A[3]
      • 使用指令:lw x10,12(x15), add x10,x12,x10, sw x10,40(x15)
      • 注意:偏移量需要是 4 的倍數。
  5. Loading and Storing Bytes(加載和儲存位元組):
    • 除了字(word)數據傳輸(lw, sw),RISC-V 還支持位元組傳輸:
      • load byte: lb
      • store byte: sb
      • load/store half-word: lh, sh
    • 示例:lb x10,3(x11),從 x11 為地址的地方加上 3,讀取下一個位元組數據,並將結果儲存在 x10。
    • RISC-V 還有「無符號位元組」加載(lbu, lhu),使用零擴展來填充 register。

上一篇
[Day03] RISC-V Instructions (1/3)
下一篇
[Day05] RISC-V Instructions (3/3)
系列文
RISC-V 與處理器之架構學習及應用21
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言